module ddr4_controler # (
    parameter integer ADDR_WIDTH = 29,  // 地址位宽
    parameter integer DATA_WIDTH = 16  // 数据位宽

)(
    input sys_clk_p,
    input sys_clk_n,
    input rst_n,
    //ddr4 connect
    output c0_ddr4_act_n ,
    output [16:0] c0_ddr4_adr , //16位的地址线给颗粒
    output [1:0] c0_ddr4_ba ,   //bank地址线给颗粒
    output [0:0] c0_ddr4_bg ,   //bank组地址线给颗粒
    output [0:0] c0_ddr4_cke ,  //CKE (Clock Enable) 信号 ，拉低为低功耗(自刷新)，不做读写
    output [0:0] c0_ddr4_odt ,  //ODT (On-Die Termination) 信号给颗粒
    output [0:0] c0_ddr4_cs_n ,  //片选信号给颗粒
    output [0:0] c0_ddr4_ck_t ,  //时钟使能信号给颗粒
    output [0:0] c0_ddr4_ck_c ,  //时钟使能信号给颗粒
    output c0_ddr4_reset_n ,
    inout [1:0] c0_ddr4_dm_dbi_n,
    inout [15:0] c0_ddr4_dq ,
    inout [1:0] c0_ddr4_dqs_c ,
    inout [1:0] c0_ddr4_dqs_t ,
    //user connect
    output c0_ddr4_ui_clk ,
    output c0_init_calib_complete,
    input [ADDR_WIDTH-1:0] app_addr_rd_min , //读 DDR4 的起始地址
    input [ADDR_WIDTH-1:0] app_addr_rd_max , //读 DDR4 的结束地址
    input [7:0] rd_bust_len , //从 DDR4 中读数据时的突发长度
    input [ADDR_WIDTH-1:0] app_addr_wr_min , //写 DDR4 的起始地址
    input [ADDR_WIDTH-1:0] app_addr_wr_max , //写 DDR4 的结束地址
    input [7:0] wr_bust_len , //从 DDR4 中写数据时的突发长度
    input wr_fifo_wclk ,
    input rd_fifo_rclk ,
    input [DATA_WIDTH-1:0] wr_fifo_wdata ,
    output [DATA_WIDTH-1:0] rd_fifo_rdata ,
    input ddr4_read_valid ,
    input wr_fifo_wen ,
    input rd_fifo_ren,
    output [7:0] wr_fifo_rcount ,
    output [7:0] rd_fifo_wcount ,
    output c0_ddr4_app_rd_data_valid,
    output [28 : 0] c0_ddr4_app_addr,
    output [127:0] rd_fifo_wdata
);

//wire define
wire [127:0] wr_fifo_rdata ;
// wire [127:0] rd_fifo_wdata ;
// wire [7:0] wr_fifo_rcount ;
// wire [7:0] rd_fifo_wcount ;
wire c0_ddr4_ui_clk_sync_rst ;
wire c0_ddr4_app_en ;
wire c0_ddr4_app_wdf_end ;
wire c0_ddr4_app_wdf_wren ;
wire c0_ddr4_app_rd_data_end ;
// wire c0_ddr4_app_rd_data_valid ;
wire c0_ddr4_app_rdy ;
wire c0_ddr4_app_wdf_rdy ;
// wire [28 : 0]c0_ddr4_app_addr ;
wire [2 : 0] c0_ddr4_app_cmd ;

//读写模块
ddr4_rw u_ddr4_rw(
    .ui_clk (c0_ddr4_ui_clk) ,
    .ui_clk_sync_rst (c0_ddr4_ui_clk_sync_rst | ~rst_n),
    //MIG 接口
    .init_calib_complete (c0_init_calib_complete) , //ddr4 初始化完成信号
    .app_rdy (c0_ddr4_app_rdy) , //MIG IP 核空闲
    .app_wdf_rdy (c0_ddr4_app_wdf_rdy) , //写空闲
    .app_rd_data_valid (c0_ddr4_app_rd_data_valid) , //读数据有效
    .app_addr (c0_ddr4_app_addr) , //ddr4 地址
    .app_en (c0_ddr4_app_en) , //MIG IP 核使能
    .app_wdf_wren (c0_ddr4_app_wdf_wren) , //ddr4 写使能
    .app_wdf_end (c0_ddr4_app_wdf_end) , //突发写当前时钟最后一个数据
    .app_cmd (c0_ddr4_app_cmd) , //用户读写命令
    //DDR4 地址参数
    .app_addr_rd_min (app_addr_rd_min) , //读 ddr4 的起始地址
    .app_addr_rd_max (app_addr_rd_max) , //读 ddr4 的结束地址
    .rd_bust_len (rd_bust_len) , //从 ddr4 中读数据时的突发长度
    .app_addr_wr_min (app_addr_wr_min) , //写 ddr4 的起始地址
    .app_addr_wr_max (app_addr_wr_max) , //写 ddr4 的结束地址
    .wr_bust_len (wr_bust_len) , //从 ddr4 中写数据时的突发长度
    //用户接口
    .rfifo_wren (rfifo_wren) , //从 ddr4 读出数据的有效使能
    .ddr4_read_valid (ddr4_read_valid) , //DDR4 读使能
    .wfifo_rcount (wr_fifo_rcount) , //wfifo 写进数据计数
    .rfifo_wcount (rd_fifo_wcount) //rfifo 剩余数据计数
);

//MIP IP核
ddr4_0 u_ddr4_0 (
  .c0_init_calib_complete(c0_init_calib_complete),        // output wire c0_init_calib_complete
  .dbg_clk(),                                      // output wire dbg_clk dbg的是调试信号
  .c0_sys_clk_p(sys_clk_p),                            // input wire c0_sys_clk_p
  .c0_sys_clk_n(sys_clk_n),                            // input wire c0_sys_clk_n
  .dbg_bus(),                                      // output wire [511 : 0] dbg_bus dbg的是调试信号
  .c0_ddr4_adr(c0_ddr4_adr),                              // output wire [16 : 0] c0_ddr4_adr
  .c0_ddr4_ba(c0_ddr4_ba),                                // output wire [1 : 0] c0_ddr4_ba
  .c0_ddr4_cke(c0_ddr4_cke),                              // output wire [0 : 0] c0_ddr4_cke
  .c0_ddr4_cs_n(c0_ddr4_cs_n),                            // output wire [0 : 0] c0_ddr4_cs_n
  .c0_ddr4_dm_dbi_n(c0_ddr4_dm_dbi_n),                    // inout wire [1 : 0] c0_ddr4_dm_dbi_n
  .c0_ddr4_dq(c0_ddr4_dq),                                // inout wire [15 : 0] c0_ddr4_dq
  .c0_ddr4_dqs_c(c0_ddr4_dqs_c),                          // inout wire [1 : 0] c0_ddr4_dqs_c
  .c0_ddr4_dqs_t(c0_ddr4_dqs_t),                          // inout wire [1 : 0] c0_ddr4_dqs_t
  .c0_ddr4_odt(c0_ddr4_odt),                              // output wire [0 : 0] c0_ddr4_odt
  .c0_ddr4_bg(c0_ddr4_bg),                                // output wire [0 : 0] c0_ddr4_bg
  .c0_ddr4_reset_n(c0_ddr4_reset_n),                      // output wire c0_ddr4_reset_n
  .c0_ddr4_act_n(c0_ddr4_act_n),                          // output wire c0_ddr4_act_n
  .c0_ddr4_ck_c(c0_ddr4_ck_c),                            // output wire [0 : 0] c0_ddr4_ck_c
  .c0_ddr4_ck_t(c0_ddr4_ck_t),                            // output wire [0 : 0] c0_ddr4_ck_t
  //用户接口
  .c0_ddr4_ui_clk(c0_ddr4_ui_clk),                        // output wire c0_ddr4_ui_clk IP核生成的时钟，用户时钟
  .c0_ddr4_ui_clk_sync_rst(c0_ddr4_ui_clk_sync_rst),      // output wire c0_ddr4_ui_clk_sync_rst IP核生成的复位信号，用户复位
  .c0_ddr4_app_en(c0_ddr4_app_en),                        // input wire c0_ddr4_app_en
  .c0_ddr4_app_hi_pri(1'b0),                // input wire c0_ddr4_app_hi_pri 用于标记来自应用层（或外设）的内存访问请求是否为高优先级请求。
  .c0_ddr4_app_wdf_end(c0_ddr4_app_wdf_end),              // input wire c0_ddr4_app_wdf_end
  .c0_ddr4_app_wdf_wren(c0_ddr4_app_wdf_wren),            // input wire c0_ddr4_app_wdf_wren
  .c0_ddr4_app_rd_data_end(c0_ddr4_app_rd_data_end),      // output wire c0_ddr4_app_rd_data_end
  .c0_ddr4_app_rd_data_valid(c0_ddr4_app_rd_data_valid),  // output wire c0_ddr4_app_rd_data_valid
  .c0_ddr4_app_rdy(c0_ddr4_app_rdy),                      // output wire c0_ddr4_app_rdy
  .c0_ddr4_app_wdf_rdy(c0_ddr4_app_wdf_rdy),              // output wire c0_ddr4_app_wdf_rdy
  .c0_ddr4_app_addr(c0_ddr4_app_addr),                    // input wire [28 : 0] c0_ddr4_app_addr
  .c0_ddr4_app_cmd(c0_ddr4_app_cmd),                      // input wire [2 : 0] c0_ddr4_app_cmd
  .c0_ddr4_app_wdf_data(wr_fifo_rdata),            // input wire [127 : 0] c0_ddr4_app_wdf_data *
  .c0_ddr4_app_wdf_mask(16'b0),            // input wire [15 : 0] c0_ddr4_app_wdf_mask,掩码 1为掩盖
  .c0_ddr4_app_rd_data(rd_fifo_wdata),              // output wire [127 : 0] c0_ddr4_app_rd_data * 这儿没有改成这个导致没接入，卡了3天
  .sys_rst(~rst_n)                                   // input wire sys_rst
);
    
ddr4_fifo_ctrl u_ddr4_fifo_ctrl (
    .rst_n (rst_n ) ,
    .wr_fifo_wclk (wr_fifo_wclk ) , //50mhz
    .wr_fifo_rclk (c0_ddr4_ui_clk ) ,//400MHZ
    .rd_fifo_wclk (c0_ddr4_ui_clk ) ,//400MHZ
    .rd_fifo_rclk (rd_fifo_rclk ) , //50MHZ
    .wr_fifo_wdata (wr_fifo_wdata ) ,
    .wr_fifo_rdata (wr_fifo_rdata ) , //output [127:0]
    .rd_fifo_wdata (rd_fifo_wdata ) , //input [127:0]
    .rd_fifo_rdata (rd_fifo_rdata ) ,
    .wr_fifo_rcount(wr_fifo_rcount) ,
    .rd_fifo_wcount(rd_fifo_wcount) , 
    .wr_fifo_wen (wr_fifo_wen ) ,
    .wr_fifo_ren (c0_ddr4_app_wdf_wren ) ,
    .rd_fifo_wen (rfifo_wren ) ,
    .rd_fifo_ren (rd_fifo_ren )
);

endmodule